package com.buwei.module.rbac.ui.controller.extend;

import java.net.URI;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import com.buwei.infrastructure.response.ResponseResult;
import com.buwei.infrastructure.response.factory.RestResultGenerator;
import com.buwei.module.common.utils.DTO;
import com.buwei.module.rbac.domain.entity.User;
import com.buwei.module.rbac.domain.repository.UserRepository;
import com.buwei.module.rbac.ui.controller.UserController;
import com.buwei.module.rbac.ui.dto.UserCreationDTO;
import com.buwei.module.rbac.ui.dto.UserUpdateDTO;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class UserCRUDController extends UserController{
	
	@Autowired
	private UserRepository userRepository;
	
	@GetMapping(value="/{username}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<User> get(@PathVariable("username") String username){
		log.info("---------------Fetching User with username {}", username);
		User result = userRepository.findByUsername(username);
		if (result == null) {
			log.error("---------------User with username {} not found.", username);
			return ResponseEntity.noContent().build(); // 204
		}
		/*
		String eTag = order.getOptLock().toString(); // 有乐观锁
		Long lastModified = order.getLastModifiedAt().getTime();
		return ResponseEntity
				.ok()
				.eTag(eTag)
				.lastModified(lastModified)
				.body(result);
        */
		return ResponseEntity.ok().body(result); // 无乐观锁
		
	}
	
	@PostMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> create(@DTO(UserCreationDTO.class) User user){
		log.info("---------------Creating User : {}", user);
		User result = userRepository.save(user);
		URI location = ServletUriComponentsBuilder
				.fromCurrentRequest()
				.path("/{username}")
				.buildAndExpand(result.getId())
				.toUri();
		return ResponseEntity.created(location).body(RestResultGenerator.genResult(result, "用户" + user.getUsername() + "创建成功!"));
		
	}

	/**
	 * @Description : DTO中的值如果没有前台赋值过来，默认为NULL，会在save时持久化NULL到数据库
	 * ---------------------------------
	 * @Author : Bu Wei
	 * @Date : Created at 2018年3月18日 下午10:27:09
	 */
	@PostMapping(value = "/{username}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> update(@PathVariable("username") String username, @DTO(UserUpdateDTO.class) User user){
		log.info("---------------Updating User with username {}", username);
		User result = userRepository.findByUsername(username);
		if (result == null) {
			log.error("---------------Updating User with username {} not found.", username);
			return ResponseEntity.ok(RestResultGenerator.genErrorResult("用户" + username + "更新失败, 用户不存在 或 已被删除!"));
		}
		userRepository.save(user);
		return ResponseEntity.ok(RestResultGenerator.genResult("用户" + username + "更新成功!"));
	}
	
	/**
	 * @Description : 
	 * 对status的post操作 = 启用用户
	 * 对status的delete操作 = 停用用户
	 * ---------------------------------
	 * @Author : Bu Wei
	 * @Date : Created at 2018年4月25日 下午10:02:08
	 */
	@PostMapping(value = "/{username}/status", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> enableUser(@PathVariable("username") String username){
		log.info("---------------Enable User with username {}", username);
		User result = userRepository.findByUsername(username);
		if (result == null) {
			log.error("---------------Enable User with username {} not found.", username);
			return ResponseEntity.ok(RestResultGenerator.genErrorResult("用户" + username + "启用失败, 用户不存在 或 已被删除!"));
		}
		userRepository.save(result.enable());
		return ResponseEntity.ok(RestResultGenerator.genResult("用户" + username + "启用成功!"));
	}
	
	/**
	 * @Description : 
	 * 对status的delete操作 = 停用用户
	 * ---------------------------------
	 * @Author : Bu Wei
	 * @Date : Created at 2018年4月25日 下午10:02:08
	 */
	@DeleteMapping(value = "/{username}/status", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> disableUser(@PathVariable("username") String username){
		log.info("---------------Disable User with username {}", username);
		User result = userRepository.findByUsername(username);
		if (result == null) {
			log.error("---------------Disable User with username {} not found.", username);
			return ResponseEntity.ok(RestResultGenerator.genErrorResult("用户" + username + "停用失败, 用户不存在 或 已被删除!"));
		}
		userRepository.save(result.enable());
		return ResponseEntity.ok(RestResultGenerator.genResult("用户" + username + "停用成功!"));
	}
	
	/**
	 * @Description : 对指定用户的password属性作delete请求会重置用户的密码
	 * ---------------------------------
	 * @Author : Bu Wei
	 * @Date : Created at 2018年4月25日 下午10:08:15
	 */
	@DeleteMapping(value = "/{username}/password", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> updatePassword(@PathVariable("username") String username){
		log.info("---------------Resetting User'password with username {}", username);
		User result = userRepository.findByUsername(username);
		if (result == null) {
			log.error("---------------Resetting User'password with username {} not found.", username);
			return ResponseEntity.ok(RestResultGenerator.genErrorResult("用户" + username + "重置密码失败, 用户不存在 或 已被删除!"));
		}
		result.encodePassword("1234567890");
		userRepository.save(result);
		return ResponseEntity.ok(RestResultGenerator.genResult("用户" + username + "重置密码成功!"));
	}
	
	@DeleteMapping(value = "/{username}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<ResponseResult<?>> delete(@PathVariable String username){
		log.info("---------------Deleting User with username {}", username);
		userRepository.deleteByUsername(username);
//		User u = userRepository.findByUsername(username);
//		u.deleteUser();
//		userRepository.save(u);
		return ResponseEntity.ok(RestResultGenerator.genResult("用户" + username + "删除成功!"));
	}
}
